<?php
/*
* Action 的基类，所有Action都必须继承该类
*/
namespace Lib;
class Action{
	public $serv;
	// 模板目录
	private $tpl_path;
	// 主题
	private $theme;
	// 挂件
	private $widgets;
	// 控制器
	public $act_name;
	// 页面ID
	public $page_id;
	// 请求方式
	public $request_method;
	// 模板变量
	private $data;
	// 动作
	public $act;
	public function __construct($server,$request_method){
		$this->serv = $server;
		$this->data = [];
		$this->theme = isset($this->serv->config['app']['theme']) && !empty($this->serv->config['app']['theme']) ? $this->serv->config['app']['theme'] : 'default';
		$classed_class = explode('\\',get_called_class());
		array_shift($classed_class);
		$this->tpl_path = strtolower(join('/',$classed_class));
		$this->act_name = \Lib\Common::getActionUrl();
		$this->page_id = abs(crc32($this->act_name));
		$this->assign('page_id',$this->page_id);
		$this->request_method = $request_method;
		$this->act = request('act','','strip_tags,trim');
		if(method_exists($this, '_init')){
			call_user_func(array($this,'_init'));
		}
	}	
	public function doGet(){
		return $this->serv->http404();
	}
	public function doPost(){
		return $this->serv->http404();
	}
	public function doUpdate(){
		return $this->serv->http404();
	}
	public function doDelete(){
		return $this->serv->http404();
	}
	public function doAdd(){
		return $this->serv->http404();
	}

	protected function assign(){
		$argvs = func_get_args();
		if(empty($argvs)){
			return;
		}
		if(is_array($argvs[0])){
			return $this->data = array_merge($this->data,$argvs[0]);
		}elseif(count($argvs)>1){
			return $this->data[$argvs[0]] = $argvs[1];
		}
	}

	protected function display($tpl_file,$data = array()){
		$data = array_merge($this->data,$data);
		extract($data);
		include($this->tpl($tpl_file,$this->theme));
		unset($data);
		$this->data = [];
	}

	public function tpl($tpl_file,$theme='default'){
		if(strpos($tpl_file, ':')){
			list($dir,$tpl_file) = explode(':',$tpl_file,2);
		}else{
			$dir = $this->tpl_path;
		}
		$shm_file = SHM_PATH.'tpls/'.$theme.'/'.$dir.'/'.$tpl_file;
		$default_shm_file = SHM_PATH.'tpls/default/'.$dir.'/'.$tpl_file;
		$real_tpl_file = TPL_PATH.$theme.'/'.$dir.'/'.$tpl_file;
		$default_real_tpl_file = TPL_PATH.'default/'.$dir.'/'.$tpl_file;
		if(is_file($shm_file)){
			if(!defined('DEBUG')){return $shm_file;}
		}elseif($theme!='default' && is_file($default_shm_file)){
			if(!defined('DEBUG')){return $default_shm_file;}
		}

		if($theme != 'default' && !is_file($tpl_file)){
			$real_tpl_file = $default_real_tpl_file;
			$shm_file = $default_shm_file;
		}
		
		if(!is_file($shm_file) || filemtime($real_tpl_file)>filemtime($shm_file)){
			if(!is_file($real_tpl_file)){
				if(is_file($shm_file))
					unlink($shm_file);
				throw new \Exception("Template file <font color='red'>".str_replace(APP_PATH,'',$real_tpl_file)."</font> not exist!", 300);
			}
			$shm_dir = dirname($shm_file);
			if(!is_dir($shm_dir)){
				mkdir($shm_dir,0755,true);
			}
			copy($real_tpl_file, $shm_file);
		}
		return $shm_file;
	}

	/**
	* 向页面插入一个挂件
	* @access public
	* @param string $name 挂件名称
	* @param array $data 参数
	* @param string $page 所在页面名称，如该挂件为所有页面公共显示的，可在多个页面上输入一个相同的名称，以保持数据统一
	* @return void
	*/
	public function widget($name,$data=[],$page=''){
		if(!isset($this->widgets[$name])){
			$w_name = ucwords($name);
			$widget = '\\Widget\\'.$w_name.'\\'.$w_name;
			if(!class_exists($widget)){
				throw new \Exception("Widget <font color='red'>{$name}</font> not exist",400);
			}
			$this->widgets[$name] = new $widget(empty($page) ? $this->page_id : abs(crc32($page)),$this);
		}
		return $this->widgets[$name]->init()->show($data);
	}

	public function checkParam($param,$to_url=null){
		if($to_url == null ){
			if(array_key_exists('HTTP_REFERER',$_SERVER)){
				$referer = $_SERVER['HTTP_REFERER'];
			}
			if(!empty($referer)){
				$start = strpos($referer,site_url());
				$to_url = substr($referer,$start+strlen(site_url()));
			}else{
				$to_url = '/os/index';
			}
		}
		
		if (empty ( $param )) {
			throw new \Exception("缺少必要的参数", 0);
		}
	}

	public function jsonError($msg){
		return $this->json(array('error'=>1,'msg'=>$msg));
	}

	public function jsonSuccess($msg){
		return $this->json(array('success'=>1,'msg'=>$msg));
	}

	public function json($data){
		return json_encode($data);
	}

	public function jsonp($data){
		$callback = request('callback','','trim');
		$ret = json_encode($data);
		if(!empty($callback)){
			set_header('Content-Type','text/javascript');
		}
		return $callback ? $callback.'('.$ret.')' : $ret;
	}

	public function validate($data,$need){
		if(empty($data) || empty($need)){
			return false;
		}
		$need_keys = array_keys($need);
		foreach($need_keys as $need_key){
			if(!isset($data[$need_key]) || empty($data[$need_key])){
				return $need[$need_key];
			}
		}
		return true;
	}

	public function addScript(){
		$scripts = func_get_args();
		$remote_script = $local_script = "";
		foreach($scripts as $script){
			if(strpos($script, 'http')===0){
				$remote_script.="<script type=\"text/javascript\" src=\"{$script}\"></script>\n";
			}else{
				$local_script .= $local_script ? ','.$script : $script;
			}
		}
		$this->assign('local_script',$local_script);
		$this->assign('remote_script',$remote_script);
	}

	public function addCss(){
		$csss = func_get_args();
		$remote_css = $local_css = "";
		foreach($csss as $css){
			if(strpos($css, 'http')===0){
				$remote_css.="<link rel=\"stylesheet\" type=\"text/css\" href=\"{$css}\"/>\n";
			}else{
				$local_css .= $local_css ? ','.$css : $css;
			}
		}
		$this->assign('local_css',$local_css);
		$this->assign('remote_css',$remote_css);
	}

	public function setTitle($title){
		$this->assign('page_title',$title);
	}

	public function setKeywords($keywords){
		$this->assign('page_keywords',$keywords);
	}

	public function setDescription($description){
		$this->assign('page_description',$description);
	}

	protected function message($message_detail, $forward_url='', $second = 5,$type="message") {
		switch ($type) {
			case "success" :
				$page_title="操作成功！";
				$img = '';
				break;
			case "error":
				$page_title="错误!";
				$img = '';
				break;
			default:
				$page_title="提示信息！";
				$img = '';
				break;
		}
		if(empty($forward_url)){
			$forward_url = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
		}
		
		$str = join("\n",['<!DOCTYPE html>',
						' <html>',
						'	<head>',
						'		<meta charset="utf-8">',
						$second && $forward_url ? "<meta http-equiv=\"refresh\" content=\"{$second};url={$forward_url}\">" : "",
						"		<title>{$page_title}</title>",
						'		</head>',
						]);
		$str .= <<<eof
				<body>
					<div style="position:absolute;left:50%;top:10%;margin-left:-250px;width:500px;min-height:80px;border:1px solid #09AFFF;">
					<h1 style="padding:0;margin:0;height:30px;line-height:30px;text-indent:7px;font-size:14px;font-family:'Microsoft YaHei';background:#09AFFF;color:#ffffff;">提示信息</h1>
					<h2 style="font-size:16px;font-weight:normal;font-family:'Microsoft YaHei';text-align:center;">
					<img src="{$img}" valign="middle"> {$message_detail}
					</h2>
					<h3 style="font-size:12px;padding:0;margin:0;text-align:center;margin-top:20px;font-weight:normal;margin-bottom:20px;">
						<a href="/" style="color:#999999;">返回首页</a>&nbsp;&nbsp;<a href="{$forward_url}" style="color:#999999;">返回上一页</a>&nbsp;&nbsp;<a href="javascript:window.close();" style="color:#999999;">关闭</a>
					</h3>
					</div>
				</body>
				</html>
eof;
		echo $str;
	}

	protected function error($message_detail, $forward_url='', $second = 5) {
		return $this->message($message_detail, $forward_url, $second ,'error');
	}

	protected function success($message_detail, $forward_url='', $second = 5 ) {
		return $this->message($message_detail, $forward_url, $second, 'success');
	}
	
	public function addFormVerify(){
		$verify_code = \Lib\Encrypt::encrypt($_SERVER['REMOTE_ADDR'].'@'.dom().'@'.microtime(true));
		return '<input type="hidden" value="'.urlencode($verify_code).'" name="_fvc_">'."\n";
	}

	public function verifyForm(){
		$verify_code = request('_fvc_','','urldecode');
		$real_data = \Lib\Encrypt::decrypt($verify_code);
		if(!empty($real_data)){
			$arr = explode('@',$real_data,3);
			if(isset($arr[0]) && isset($arr[1]) && isset($arr[2]) && is_ip($arr[0]) && $arr[1]==dom() && is_numeric($arr[2])){
				return true;
			}
		}
		return false;
	}

	public function hasFormVerify(){
		return request('_fvc_') ? true : false;
	}
}